home *** CD-ROM | disk | FTP | other *** search
/ EuroCD 3 / EuroCD 3.iso / Programming / vbcc / vcpp / tokens.c < prev    next >
C/C++ Source or Header  |  1998-06-24  |  7KB  |  362 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "cpp.h"
  5.  
  6. static char wbuf[2*OBS];
  7. static char *wbp = wbuf;
  8.  
  9. /*
  10.  * 1 for tokens that don't need whitespace when they get inserted
  11.  * by macro expansion
  12.  */
  13. static const char wstab[] = {
  14.     0,    /* END */
  15.     0,    /* UNCLASS */
  16.     0,    /* NAME */
  17.     0,    /* NUMBER */
  18.     0,    /* STRING */
  19.     0,    /* CCON */
  20.     1,    /* NL */
  21.     0,    /* WS */
  22.     0,    /* DSHARP */
  23.     0,    /* EQ */
  24.     0,    /* NEQ */
  25.     0,    /* LEQ */
  26.     0,    /* GEQ */
  27.     0,    /* LSH */
  28.     0,    /* RSH */
  29.     0,    /* LAND */
  30.     0,    /* LOR */
  31.     0,    /* PPLUS */
  32.     0,    /* MMINUS */
  33.     0,    /* ARROW */
  34.     1,    /* SBRA */
  35.     1,    /* SKET */
  36.     1,    /* LP */
  37.     1,    /* RP */
  38.     0,    /* DOT */
  39.     0,    /* AND */
  40.     0,    /* STAR */
  41.     0,    /* PLUS */
  42.     0,    /* MINUS */
  43.     0,    /* TILDE */
  44.     0,    /* NOT */
  45.     0,    /* SLASH */
  46.     0,    /* PCT */
  47.     0,    /* LT */
  48.     0,    /* GT */
  49.     0,    /* CIRC */
  50.     0,    /* OR */
  51.     0,    /* QUEST */
  52.     0,    /* COLON */
  53.     0,    /* ASGN */
  54.     1,    /* COMMA */
  55.     0,    /* SHARP */
  56.     1,    /* SEMIC */
  57.     1,    /* CBRA */
  58.     1,    /* CKET */
  59.     0,    /* ASPLUS */
  60.      0,    /* ASMINUS */
  61.      0,    /* ASSTAR */
  62.      0,    /* ASSLASH */
  63.      0,    /* ASPCT */
  64.      0,    /* ASCIRC */
  65.      0,    /* ASLSH */
  66.     0,    /* ASRSH */
  67.      0,    /* ASOR */
  68.      0,    /* ASAND */
  69.     0,    /* ELLIPS */
  70.     0,    /* DSHARP1 */
  71.     0,    /* NAME1 */
  72.     0,    /* DEFINED */
  73.     0,    /* UMINUS */
  74. };
  75.  
  76. void
  77. maketokenrow(int size, Tokenrow *trp)
  78. {
  79.     trp->max = size;
  80.     if (size>0)
  81.         trp->bp = (Token *)domalloc(size*sizeof(Token));
  82.     else
  83.         trp->bp = NULL;
  84.     trp->tp = trp->bp;
  85.     trp->lp = trp->bp;
  86. }
  87.  
  88. Token *
  89. growtokenrow(Tokenrow *trp)
  90. {
  91.     int ncur = trp->tp - trp->bp;
  92.     int nlast = trp->lp - trp->bp;
  93.  
  94.     trp->max = 3*trp->max/2 + 1;
  95.     trp->bp = (Token *)realloc(trp->bp, trp->max*sizeof(Token));
  96.     trp->lp = &trp->bp[nlast];
  97.     trp->tp = &trp->bp[ncur];
  98.     return trp->lp;
  99. }
  100.  
  101. /*
  102.  * Compare a row of tokens, ignoring the content of WS; return !=0 if different
  103.  */
  104. int
  105. comparetokens(Tokenrow *tr1, Tokenrow *tr2)
  106. {
  107.     Token *tp1, *tp2;
  108.  
  109.     tp1 = tr1->tp;
  110.     tp2 = tr2->tp;
  111.     if (tr1->lp-tp1 != tr2->lp-tp2)
  112.         return 1;
  113.     for (; tp1<tr1->lp ; tp1++, tp2++) {
  114.         if (tp1->type != tp2->type
  115.          || (tp1->wslen==0) != (tp2->wslen==0)
  116.          || tp1->len != tp2->len
  117.          || strncmp((char*)tp1->t, (char*)tp2->t, tp1->len)!=0)
  118.             return 1;
  119.     }
  120.     return 0;
  121. }
  122.  
  123. /*
  124.  * replace ntok tokens starting at dtr->tp with the contents of str.
  125.  * tp ends up pointing just beyond the replacement.
  126.  * Canonical whitespace is assured on each side.
  127.  */
  128. void
  129. insertrow(Tokenrow *dtr, int ntok, Tokenrow *str)
  130. {
  131.     int nrtok = rowlen(str);
  132.  
  133.     dtr->tp += ntok;
  134.     adjustrow(dtr, nrtok-ntok);
  135.     dtr->tp -= ntok;
  136.     movetokenrow(dtr, str);
  137.     makespace(dtr);
  138.     dtr->tp += nrtok;
  139.     makespace(dtr);
  140. }
  141.  
  142. /*
  143.  * make sure there is WS before trp->tp, if tokens might merge in the output
  144.  */
  145. void
  146. makespace(Tokenrow *trp)
  147. {
  148.     uchar *tt;
  149.     Token *tp = trp->tp;
  150.  
  151.     if (tp >= trp->lp)
  152.         return;
  153.     if (tp->wslen) {
  154.         if (tp->flag&XPWS
  155.          && (wstab[tp->type] || trp->tp>trp->bp && wstab[(tp-1)->type])) {
  156.             tp->wslen = 0;
  157.             return;
  158.         }
  159.         tp->t[-1] = ' ';
  160.         return;
  161.     }
  162.     if (wstab[tp->type] || trp->tp>trp->bp && wstab[(tp-1)->type])
  163.         return;
  164.     tt = newstring(tp->t, tp->len, 1);
  165.     *tt++ = ' ';
  166.     tp->t = tt;
  167.     tp->wslen = 1;
  168.     tp->flag |= XPWS;
  169. }
  170.  
  171. /*
  172.  * Copy an entire tokenrow into another, at tp.
  173.  * It is assumed that there is enough space.
  174.  *  Not strictly conforming.
  175.  */
  176. void
  177. movetokenrow(Tokenrow *dtr, Tokenrow *str)
  178. {
  179.     int nby;
  180.  
  181.     /* nby = sizeof(Token) * (str->lp - str->bp); */
  182.     nby = (char *)str->lp - (char *)str->bp;
  183.     memmove(dtr->tp, str->bp, nby);
  184. }
  185.  
  186. /*
  187.  * Move the tokens in a row, starting at tr->tp, rightward by nt tokens;
  188.  * nt may be negative (left move).
  189.  * The row may need to be grown.
  190.  * Non-strictly conforming because of the (char *), but easily fixed
  191.  */
  192. void
  193. adjustrow(Tokenrow *trp, int nt)
  194. {
  195.     int nby, size;
  196.  
  197.     if (nt==0)
  198.         return;
  199.     size = (trp->lp - trp->bp) + nt;
  200.     while (size > trp->max)
  201.         growtokenrow(trp);
  202.     /* nby = sizeof(Token) * (trp->lp - trp->tp); */
  203.     nby = (char *)trp->lp - (char *)trp->tp;
  204.     if (nby)
  205.         memmove(trp->tp+nt, trp->tp, nby);
  206.     trp->lp += nt;
  207. }
  208.  
  209. /*
  210.  * Copy a row of tokens into the destination holder, allocating
  211.  * the space for the contents.  Return the destination.
  212.  */
  213. Tokenrow *
  214. copytokenrow(Tokenrow *dtr, Tokenrow *str)
  215. {
  216.     int len = rowlen(str);
  217.  
  218.     maketokenrow(len, dtr);
  219.     movetokenrow(dtr, str);
  220.     dtr->lp += len;
  221.     return dtr;
  222. }
  223.  
  224. /*
  225.  * Produce a copy of a row of tokens.  Start at trp->tp.
  226.  * The value strings are copied as well.  The first token
  227.  * has WS available.
  228.  */
  229. Tokenrow *
  230. normtokenrow(Tokenrow *trp)
  231. {
  232.     Token *tp;
  233.     Tokenrow *ntrp = new(Tokenrow);
  234.     int len;
  235.  
  236.     len = trp->lp - trp->tp;
  237.     if (len<=0)
  238.         len = 1;
  239.     maketokenrow(len, ntrp);
  240.     for (tp=trp->tp; tp < trp->lp; tp++) {
  241.         *ntrp->lp = *tp;
  242.         if (tp->len) {
  243.             ntrp->lp->t = newstring(tp->t, tp->len, 1);
  244.             *ntrp->lp->t++ = ' ';
  245.             if (tp->wslen)
  246.                 ntrp->lp->wslen = 1;
  247.         }
  248.         ntrp->lp++;
  249.     }
  250.     if (ntrp->lp > ntrp->bp)
  251.         ntrp->bp->wslen = 0;
  252.     return ntrp;
  253. }
  254.  
  255. /*
  256.  * Debugging
  257.  */
  258. void
  259. peektokens(Tokenrow *trp, char *str)
  260. {
  261.     Token *tp;
  262.  
  263.     tp = trp->tp;
  264.     flushout();
  265.     if (str)
  266.         fprintf(stderr, "%s ", str);
  267.     if (tp<trp->bp || tp>trp->lp)
  268.         fprintf(stderr, "(tp offset %d) ", tp-trp->bp);
  269.     for (tp=trp->bp; tp<trp->lp && tp<trp->bp+32; tp++) {
  270.         if (tp->type!=NL) {
  271.             int c = tp->t[tp->len];
  272.             tp->t[tp->len] = 0;
  273.             fprintf(stderr, "%s", tp->t);
  274.             tp->t[tp->len] = c;
  275.         }
  276.         if (tp->type==NAME) {
  277.             fprintf(stderr, tp==trp->tp?"{*":"{");
  278.             prhideset(tp->hideset);
  279.             fprintf(stderr, "} ");
  280.         } else
  281.             fprintf(stderr, tp==trp->tp?"{%x*} ":"{%x} ", tp->type);
  282.     }
  283.     fprintf(stderr, "\n");
  284.     fflush(stderr);
  285. }
  286.  
  287. void
  288. puttokens(Tokenrow *trp)
  289. {
  290.     Token *tp;
  291.     int len;
  292.     uchar *p;
  293.  
  294.     if (verbose)
  295.         peektokens(trp, "");
  296.     tp = trp->bp;
  297.     for (; tp<trp->lp; tp++) {
  298.         len = tp->len+tp->wslen;
  299.         p = tp->t-tp->wslen;
  300.         while (tp<trp->lp-1 && p+len == (tp+1)->t - (tp+1)->wslen) {
  301.             tp++;
  302.             len += tp->wslen+tp->len;
  303.         }
  304.         memcpy(wbp, p, len);
  305.         wbp += len;
  306.         if (wbp >= &wbuf[OBS]) {
  307.             write(1, wbuf, OBS);
  308.             if (wbp > &wbuf[OBS])
  309.                 memcpy(wbuf, wbuf+OBS, wbp - &wbuf[OBS]);
  310.             wbp -= OBS;
  311.         }
  312.     }
  313.     trp->tp = tp;
  314.     if (cursource->fd==0)
  315.         flushout();
  316. }
  317.  
  318. void
  319. flushout(void)
  320. {
  321.     if (wbp>wbuf) {
  322.         write(1, wbuf, wbp-wbuf);
  323.         wbp = wbuf;
  324.     }
  325. }
  326.  
  327. /*
  328.  * turn a row into just a newline
  329.  */
  330. void
  331. setempty(Tokenrow *trp)
  332. {
  333.     trp->tp = trp->bp;
  334.     trp->lp = trp->bp+1;
  335.     *trp->bp = nltoken;
  336. }
  337.  
  338. /*
  339.  * generate a number
  340.  */
  341. char *
  342. outnum(char *p, int n)
  343. {
  344.     if (n>=10)
  345.         p = outnum(p, n/10);
  346.     *p++ = n%10 + '0';
  347.     return p;
  348. }
  349.  
  350. /*
  351.  * allocate and initialize a new string from s, of length l, at offset o
  352.  * Null terminated.
  353.  */
  354. uchar *
  355. newstring(uchar *s, int l, int o)
  356. {
  357.     uchar *ns = (uchar *)domalloc(l+o+1);
  358.  
  359.     ns[l+o] = '\0';
  360.     return (uchar*)strncpy((char*)ns+o, (char*)s, l) - o;
  361. }
  362.